﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Repetition.Domain;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Transform;
using NHibernate.Linq;

namespace Repetition.Persistence.FluentNHibernate
{
    public class ProblemRepository : Repository<Problem>, IProblemRepository
    {
        public ProblemRepository()
            : base() { }

        public ProblemRepository(ISession session)
            : base(session) { }

        public ICollection<Problem> GetBySubject(string subjectName)
        {
            // Get the subject with the specified name:
            var subject = (from s in Session.Linq<Subject>()
                           where s.Name == subjectName
                           select s).First();

            // Get all problems with the found subject:
            var problems = from problem in Session.Linq<Problem>()
                           where problem.Subjects.Contains(subject)
                           select problem;

            return problems.ToList();
        }

        public ICollection<Problem> GetBySubjects(ICollection<Subject> subjects)
        {
            if (subjects.Count <= 0)
                return new List<Problem>();

            // This query causes a SQL execution error, but it is a better solution
            // than the hack below.
            /*
            var query = from problem in Session.Linq<Problem>() 
                        where problem.Subjects.Intersect(subjects).Count() > 0
                        select problem;
             */

            // This is a very inefficient query...
            IEnumerable<Problem> problems = new List<Problem>();
            IEnumerable<Problem> query;

            foreach (var subject in subjects)
            {
                query = from problem in Session.Linq<Problem>()
                        where problem.Subjects.Contains(subject)
                        select problem;

                problems = problems.Union(query.ToList());
            }

            return problems.ToList();
        }
    }
}
